package mirrormonkey.util;

import junit.framework.Assert;

import org.junit.Test;

/**
 * Contains test cases for <tt>IdGenerator</tt>.
 * 
 * @author Philipp Christian Loewner
 * 
 */
public class IdGeneratorTest {

	/**
	 * Tests if the first ID can be passed to the constructor.
	 */
	@Test
	public void testSetFirstId() {
		int first = 0;
		IdGenerator g = new IdGenerator(first);
		Assert.assertEquals(first, g.generateAndReserve());
	}

	/**
	 * Tests if IDs are generated in ascending order.
	 */
	@Test
	public void testGenerateSequential() {
		IdGenerator g = new IdGenerator();
		int last = g.generateAndReserve();
		for (int i = 0; i < 10; i++) {
			int next = g.generateAndReserve();
			Assert.assertEquals(last + 1, next);
			last = next;
		}
	}

	/**
	 * Tests if IDs that are reserved are skipped when generating a new ID.
	 */
	@Test
	public void testSkipReserved() {
		IdGenerator g = new IdGenerator(0);
		for (int i = 0; i < 5; i++) {
			g.reserve(i);
		}
		Assert.assertEquals(5, g.generateAndReserve());
	}

	/**
	 * Tests if IDs are reserved after they have been returned by
	 * <tt>generateAndReserve</tt>.
	 */
	@Test
	public void testIdReserve() {
		IdGenerator g = new IdGenerator(0);
		g.generateAndReserve();
		g.setNextId(0);
		Assert.assertEquals(1, g.generateAndReserve());
	}

	/**
	 * Tests if trying to explicitly reserve an already reserved ID provokes an
	 * exception
	 */
	@Test(expected = IllegalStateException.class)
	public void testIllegalReserveReject() {
		IdGenerator g = new IdGenerator();
		g.reserve(0);
		g.reserve(0);
	}

	/**
	 * Tests if IDs that were reserved are no longer skipped after
	 * <tt>release</tt> has been called for them.
	 */
	@Test
	public void testIdRelease() {
		IdGenerator g = new IdGenerator();
		g.reserve(0);
		g.release(0);
		g.setNextId(0);
		Assert.assertEquals(0, g.generateAndReserve());
	}

}
